<?php

namespace App\Http\Controllers\ChopHand;

use App\App\Services\Web\UserService;
use App\Contracts\Repositories\ActivityRepository as ActivityRepositoryContact;
use App\Contracts\Services\Storage\StorageService as StorageServiceContract;
use App\Entities\Activity;
use App\Entities\ActivityModel;
use App\Entities\ChopHand;
use App\Entities\ChopHandPaper;
use App\Entities\ChopHandSheet;
use App\Http\Controllers\Activity\BaseController as BaseActivityController;
use App\Morefun\Publishing\Publisher;
use Carbon\Carbon;
use Illuminate\Container\Container;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;

class ActivityController extends BaseActivityController
{
    public function __construct(UserService $user, ActivityRepositoryContact $activities)
    {
        parent::__construct($user, $activities);
    }

    public function show($id)
    {
        $activity = $this->activities->findOne($id);

        if (null === $activity) {
            return response()->failed('没有找到资源');
        }

        $storage = Container::getInstance()->make(StorageServiceContract::class);

        $translated = [
            'id'               => $activity->id,
            'category'         => $activity->category,
            'name'             => $activity->name,
            'start_time'       => $activity->startTime,
            'end_time'         => $activity->endTime,
            'limit'            => \GuzzleHttp\json_decode($activity->limit),
            'background_img'   => $storage->toHttpUrl($activity->backgroundImg),
            'background_color' => $activity->backgroundColor,
            'description'      => $activity->description,
            'app_url'          => $activity->app_url,
            'publishing'       => \GuzzleHttp\json_decode($activity->publishing_ways, true),
            'shares'           => $this->formatShares($activity->shares),
        ];

        // $quizzes = Quiz::withOptions()->where('activity_id', $id)
        $quizzes = ChopHand::withOptions()->where('activity_id', $id)
            ->orderBy('created_at', 'ASC')
            ->get(['id', 'type', 'title', 'configurations', 'validations']);

        return response()->success([
            'activity' => $translated,
            'chopHand'  => $quizzes,
        ]);
    }

    public function useable(Request $request, $id)
    {
        $activity = $this->activities->findOne($id);

        if (null === $activity) {
            return response()->success([
                'useable' => false,
                'reason'  => 'act-does-not-exist',
                'comment' => '活动不存在',
                'chopHand' => [],
            ]);
        }

        if ($activity->isPaused) {
            return response()->success([
                'useable' => false,
                'reason'  => 'act-does-not-exist',
                'comment' => '活动不存在',
                'chopHand' => [],
            ]);
        }

        $now = Carbon::now()->toDateTimeString();

        if ($now < $activity->startTime) {
            return response()->success([
                'useable' => false,
                'reason'  => 'act-does-not-start',
                'comment' => '活动还没开始',
                'chopHand' => [],
            ]);
        }

        if ($now > $activity->endTime) {
            return response()->success([
                'useable' => false,
                'reason'  => 'act-already-end',
                'comment' => '活动已经结束',
                'chopHand' => [],
            ]);
        }

        $uid = $request->get('uid', 1);

        $has = ChopHandPaper::query()->where([['activity_id', '=', $id], ['uid', '=', $uid]])->exists();

        if ($has) {
            return response()->success([
                'useable' => false,
                'reason'  => 'already-involved',
                'comment' => '用户已参与该活动',
                'chopHand' => $this->makeOriginalPaper($id, $uid),
            ]);
        }

        return response()->success([
            'useable' => true,
            'reason'  => null,
            'comment' => null,
            'chopHand' => [],
        ]);
    }

    public function notRelated(Request $request)
    {
        $without = $request->get('without');
        $type = $request->get('type');

        $query = Activity::query();
        $now = Carbon::now()->toDateTimeString();

        $query->where('endTime', '<', $now);

        if ($type) {
            $modelId = ActivityModel::query()->where('rule', $type)->value('id');
            if ($modelId) {
                $query->where('model_id', $modelId);
            }
        }

        if ($without) {
            $query->where('id', '!=', $without);
        }

        return response()->success($query->get(['id', 'name']));
    }

    protected function getRulesForCreate()
    {
        return [
            'name'                 => 'required|max:255',
            'category'             => 'required|in:1,2',
            'start_time'           => 'required|date',
            'end_time'             => 'required|date|after:start_time',
            'model_id'             => 'required',
            'template_id'          => 'required',
            'description'          => 'min:1',
            'validations'          => 'array',
            'validations.type'     => 'in:IP,MOBILE,VERIFY_CODE,PASSWORD',
            'validations.password' => 'required_if:validations.type,PASSWORD',
            'shares'               => 'array',
            'shares.title'         => 'required_if:shares.isopen,on',
            'shares.content'       => 'required_if:shares.isopen,on',
        ];
    }

    protected function getRulesForUpdate()
    {
        return [
            'name'                 => 'max:255',
            'category'             => 'in:1,2',
            'start_time'           => 'date',
            'end_time'             => 'date|after:startTime',
            'description'          => 'min:1',
            'validations'          => 'array',
            'validations.type'     => 'in:IP,MOBILE,VERIFY_CODE,PASSWORD',
            'validations.password' => 'required_if:validations.type,PASSWORD',
            'relation'             => 'array',
            'relation.id'          => 'uuid',
        ];
    }

    protected function parseRules(Request $request)
    {
        return json_encode([
            'validations' => $request->json('validations', []),
            // 关联其他活动
            'relation'    => ['id' => $request->get('relation.id', '')],
        ]);
    }

    protected function parseLimits(Request $request)
    {
        return '{}';
    }

    protected function createdEvents(Request $request, Activity $activity)
    {
        // TODO: Implement createdEvents() method.
    }

    protected function updatedEvents(Request $request, Activity $activity)
    {
        // TODO: Implement updatedEvents() method.
    }

    protected function makeOriginalPaper($activityId, $uid)
    {
        $quizzes = ChopHand::with([
            'options' => function ($query) {
                return $query->select(['id', 'chopHand_id', 'text', 'resource', 'fillable'])
                    ->orderBy('created_at', 'ASC');
            },
        ])
            ->where('activity_id', $activityId)
            ->orderBy('created_at', 'ASC')
            ->get(['id', 'activity_id', 'title', 'configurations', 'validations', 'type']);

        $paperId = ChopHandPaper::query()
            ->where('activity_id', $activityId)
            ->where('uid', $uid)
            ->value('id');
        /*
        $paper = QuizPaper::with([
            'sheets' => function ($query) {
                return $query->select(['quiz_id', 'option_id', 'fill_content', 'paper_id']);
            }
        ])
            ->where('activity_id', $activityId)
            ->where('uid', $uid)
            ->first(['id', 'activity_id', 'uid']);
        */
        $sheets = ChopHandSheet::query()
            ->where('activity_id', $activityId)
            ->where('paper_id', $paperId)
            ->get(['chopHand_id', 'option_id', 'fill_content', 'paper_id']);

        $answers = [];
        foreach ($sheets as $sheet) {
            $answers[$sheet->quiz_id] = [
                'options'  => $sheet->option_id,
                'contents' => $sheet->fill_content,
            ];
        }
        $origin = [];
        $storage = Container::getInstance()->make(StorageServiceContract::class);
        foreach ($quizzes as $of => $quiz) {
            $selected = isset($answers[$quiz->id]) ? $answers[$quiz->id] : [];
            $origin[$of]['title'] = $quiz->title;
            $origin[$of]['configurations'] = $quiz->configurations;
            $origin[$of]['validations'] = $quiz->validations;
            $origin[$of]['type'] = $quiz->type;

            if ($quiz->type === Quiz::TYPE_FILL_BLANK) {
                $origin[$of]['options'] = implode(' ', isset($selected['contents']) ? $selected['contents'] : []);
            } else {
                foreach ($quiz->options as $i => $option) {
                    if (isset($selected['options'])) {
                        $fillOf = 0;
                        $origin[$of]['options'][] = [
                            'text'         => $option->text,
                            'selected'     => in_array($option->id, $selected['options'], false),
                            'resource'     => $storage->toHttpUrl($option->resource),
                            'fill_content' => isset($selected['contents'][$fillOf]) ? $selected['contents'][$fillOf] : '',
                        ];
                        if ($option->fillable) {
                            ++$fillOf;
                        }
                    } else {
                        $origin[$of]['options'] = [];
                    }
                }
            }
        }

        return $origin;
    }
}
